package com.landscope.central.utils;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.landscope.central.controller.api.dto.ApiProjectDto;
import com.landscope.central.entity.Role;
import com.landscope.central.entity.User;

import java.util.*;

/**
 * token工具
 *
 * @author qzp
 * @version v1.0
 * @date 2021/6/28 14:42
 **/
public class TokenUtil {

    private static final String SECRET = "7PbIFZYg";

    /**
     * 生成用户凭证，其中需要包含用户基本信息，以及用户管理的子系统
     *
     * @param user:
     * @return {@link * @return java.lang.String}
     * @throws
     * @author 瞿子朋
     * @date 2021/6/28 15:24
     * @version v1.0
     **/
    public static String createUserAccessToken(User user, List<ApiProjectDto> projectDtoList, String rolePermissionCode) {
        StringBuffer stringBuffer = new StringBuffer();
        for (ApiProjectDto dto : projectDtoList) {
            stringBuffer.append(dto.getCode());
            stringBuffer.append(",");
        }
        String str = stringBuffer.toString();
        if (str.endsWith(","))
            str = str.substring(0, str.length() - 1);

        JSONObject data = new JSONObject();
        data.put("projectList", str);
        JSONObject userObj = new JSONObject();
        userObj.put("id", user.getId());
        userObj.put("manageProjectCodes", user.getManageProjectCodes());
        userObj.put("name", user.getName());
        userObj.put("rolePermissionCode", rolePermissionCode);
        data.put("user", userObj);

        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.HOUR, 8); // token过期时间8小时
//        nowTime.add(Calendar.SECOND, 8); // token过期时间8秒
        //过期时间
        Date expiresDate = nowTime.getTime();
        Map<String, Object> map = new HashMap<>();
        //声明类型和方法
        map.put("typ", "JWT");
        map.put("alg", "HS256");
        String token = JWT.create()
                .withHeader(map)
                //自定义参数
                .withClaim("auth", data.toString())
                //过期时间
                .withExpiresAt(expiresDate)
                .withIssuedAt(new Date())
                .sign(Algorithm.HMAC256(SECRET));
        return token;
    }

    /**
     * 管理用户生成token
     *
     * @param user:
     * @return {@link * @return java.lang.String}
     * @throws
     * @author 瞿子朋
     * @date 2021/6/28 14:48
     * @version v1.0
     **/
    public static String createToken(User user) {
        Calendar nowTime = Calendar.getInstance();
//        nowTime.add(Calendar.HOUR, 8); // token过期时间8小时
        nowTime.add(Calendar.SECOND, 8); // token过期时间8小时
        //过期时间
        Date expiresDate = nowTime.getTime();
        Map<String, Object> map = new HashMap<>();
        //声明类型和方法
        map.put("typ", "JWT");
        map.put("alg", "HS256");
        String token = JWT.create()
                .withHeader(map)
                //自定义参数
                .withClaim("id", user.getId())
                //过期时间
                .withExpiresAt(expiresDate)
                .withIssuedAt(new Date())
                .sign(Algorithm.HMAC256(SECRET));
        return token;
    }

    /**
     * token验证
     *
     * @param token:
     * @return {@link * @return java.util.Map<java.lang.String,com.auth0.jwt.interfaces.Claim>}
     * @throws
     * @author 瞿子朋
     * @date 2021/6/28 14:50
     * @version v1.0
     **/
    public static Map<String, Claim> verifyToken(String token) {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT jwt = verifier.verify(token);
        return jwt.getClaims();
    }

    public static void main(String[] strs) {
        String str = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoIjoie1wicHJvamVjdExpc3RcIjpcInN1YnMwMDEtcGJnLHN1YnMwMDEtaGNwXCIsXCJ1c2VyXCI6e1wiaWRcIjoxfX0iLCJleHAiOjE2MjUwNjcyOTgsImlhdCI6MTYyNTAzODQ5OH0.9WK_hEsZRjDIfAz2dM0lD03omVXhZMSXqlfe5I-8jZo";
        Map<String, Claim> map = verifyToken(str);
        for (String key : map.keySet()) {
            System.out.println(key + ":" + map.get(key).asString());
        }
    }
}
